Completed
Push — master ( 72e4cc...ad5219 )
by Sander
01:15
created

passwordgen.js ➔ generatePassword   F

Complexity

Conditions 19
Paths 280

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 19
c 1
b 0
f 0
nc 280
nop 8
dl 0
loc 30
rs 3.6524

How to fix   Complexity    Many Parameters   

Complexity

Complex classes like passwordgen.js ➔ generatePassword often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
/**
2
 * Nextcloud - passman
3
 *
4
 * @copyright Copyright (c) 2016, Sander Brand ([email protected])
5
 * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel ([email protected])
6
 * @license GNU AGPL version 3 or any later version
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as
10
 * published by the Free Software Foundation, either version 3 of the
11
 * License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
function Arcfour () {
23
    this.j = this.i = 0, this.S = []
24
}
25
26
function ARC4init (r) {
27
    var t, n, e;
28
    for (t = 0; 256 > t; ++t)this.S[t] = t
29
    for (t = n = 0; 256 > t; ++t)n = n + this.S[t] + r[t % r.length] & 255, e = this.S[t], this.S[t] = this.S[n], this.S[n] = e
30
    this.j = this.i = 0
31
}
32
33
function ARC4next () {
34
    var r;
35
    return this.i = this.i + 1 & 255, this.j = this.j + this.S[this.i] & 255, r = this.S[this.i], this.S[this.i] = this.S[this.j], this.S[this.j] = r, this.S[r + this.S[this.i] & 255]
36
}
37
38
function prng_newstate () {
39
    return new Arcfour
40
}
41
42
function generatePassword (r, t, n, e, o, i, p, g) {
43
    var _, a, s, f, d, h, u, l, c, v, w, y, m;
44
    if (void 0 === r && (r = 8 + get_random(0, 1)), r > 256 && (r = 256, document.getElementById("length").value = 256), i > 256 && (i = 256), void 0 === t && (t = !0), void 0 === n && (n = !0), void 0 === e && (e = !0), void 0 === o && (o = !1), void 0 === i && (i = 0), void 0 === p && (p = !1), void 0 === g && (g = !0), _ = 0, a = 0, s = 0, g && (_ = a = s = 1), f = [], n && _ > 0)for (d = 0; _ > d; d++)f[f.length] = "L"
45
    if (t && a > 0)for (d = 0; a > d; d++)f[f.length] = "U"
46
    if (e && i > 0)for (d = 0; i > d; d++)f[f.length] = "D"
47
    if (o && s > 0)for (d = 0; s > d; d++)f[f.length] = "S"
48
    for (; f.length < r;)f[f.length] = "A"
49
    for (f.sort(function () {
50
        return 2 * get_random(0, 1) - 1
51
    }), h = "", u = "abcdefghjkmnpqrstuvwxyz", p || (u += "ilo"), n && (h += u), l = "ABCDEFGHJKMNPQRSTUVWXYZ", p || (l += "ILO"), t && (h += l), c = "23456789", p || (c += "10"), e && (h += c), v = "!@#$%^&*", o && (h += v), w = "", y = 0; r > y; y++) {
52
        switch (f[y]) {
53
            case"L":
54
                m = u;
55
                break;
56
            case"U":
57
                m = l;
58
                break;
59
            case"D":
60
                m = c;
61
                break;
62
            case"S":
63
                m = v;
64
                break;
65
            case"A":
66
                m = h
67
        }
68
        d = get_random(0, m.length - 1), w += m.charAt(d)
69
    }
70
    return w
71
}
72
73
function rng_seed_int (r) {
74
    rng_pool[rng_pptr++] ^= 255 & r, rng_pool[rng_pptr++] ^= r >> 8 & 255, rng_pool[rng_pptr++] ^= r >> 16 & 255, rng_pool[rng_pptr++] ^= r >> 24 & 255, rng_pptr >= rng_psize && (rng_pptr -= rng_psize)
75
}
76
77
function rng_seed_time () {
78
    rng_seed_int((new Date).getTime())
79
}
80
81
function rng_get_byte () {
82
    if (null == rng_state) {
83
        for (rng_seed_time(), rng_state = prng_newstate(), rng_state.init(rng_pool), rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)rng_pool[rng_pptr] = 0
84
        rng_pptr = 0
85
    }
86
    return rng_state.next()
87
}
88
89
function rng_get_bytes (r) {
90
    var t;
91
    for (t = 0; t < r.length; ++t)r[t] = rng_get_byte()
92
}
93
94
function SecureRandom () {
95
}
96
97
function get_random (r, t) {
98
    var n, e, o, i = t - r + 1
99
    for (rng_seed_time(), n = [], e = 0; 4 > e; e++)n[e] = 0
100
    for (rng_get_bytes(n), o = 0, e = 0; 4 > e; e++)o *= 256, o += n[e]
101
    return o %= i, o += r
102
}
103
104
function get_random_password (r, t) {
105
    var n;
106
    var pwlen, newpw;
107
    for ("number" != typeof r && (r = 12), "number" != typeof t && (t = 16), r > t && (n = r, r = t, t = n), pwlen = get_random(r, t), newpw = ""; newpw.length < pwlen;)newpw += String.fromCharCode(get_random(32, 127))
108
    return newpw
109
}
110
111
var rng_psize, rng_state, rng_pool, rng_pptr, t, z, crypt_obj, num, buf, i
112
if (Arcfour.prototype.init = ARC4init, Arcfour.prototype.next = ARC4next, rng_psize = 256, null == rng_pool) {
113
    /** global: navigator */
114
    if (rng_pool = [], rng_pptr = 0, "undefined" != typeof navigator && "Netscape" == navigator.appName && navigator.appVersion < "5" && "undefined" != typeof window && window.crypto)for (z = window.crypto.random(32), t = 0; t < z.length; ++t)rng_pool[rng_pptr++] = 255 & z.charCodeAt(t)
115
    try {
116
        if (crypt_obj = null, "undefined" != typeof window && void 0 !== window.crypto ? crypt_obj = window.crypto : "undefined" != typeof window && void 0 !== window.msCrypto && (crypt_obj = window.msCrypto), void 0 !== crypt_obj && "function" == typeof crypt_obj.getRandomValues && rng_psize > rng_pptr)for (num = Math.floor((rng_psize - rng_pptr) / 2) + 1, buf = new Uint16Array(num), crypt_obj.getRandomValues(buf), i = 0; i < buf.length; i++)t = buf[i], rng_pool[rng_pptr++] = t >>> 8, rng_pool[rng_pptr++] = 255 & t
117
    } catch (e) {
118
    }
119
    for (; rng_psize > rng_pptr;)t = Math.floor(65536 * sjcl.random.randomWords(1)), rng_pool[rng_pptr++] = t >>> 8, rng_pool[rng_pptr++] = 255 & t
120
    rng_pptr = 0, rng_seed_time()
121
}
122
SecureRandom.prototype.nextBytes = rng_get_bytes;